﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;

namespace kompot_wtf
{
    public class Zombie : GameObject
    {
        //float moveSpeed = 200.0f;

        bool shownInRadar = false;

        public static void ResetZombieRadarStates(List<Zombie> zombies)
        {
            for (int i = 0; i < zombies.Count; i++)
                zombies[i].shownInRadar = false;
        }

        public static void CalcMoves(List<Zombie> zombies, Player player, float delta)
        {
            const float repulsRadiusSquared = 40000.0f;

            List<Zombie> toRemove = new List<Zombie>();

            for (int i = 0; i < zombies.Count; i++)
            {
                Zombie zomb = zombies[i];

                // radar kod powinien byc gdzie indziej ale well...

                if (((zomb.Position - player.Position).Length() < player.CurrentRadarRadius) && !zomb.shownInRadar && GameState.state == GameState.State.THIEF)
                {
                    zomb.shownInRadar = true;
                    FullScreenEffects.AddEnemyRadar(zomb.Position);
                }

                // koniec radar kod



                if (GameObject.CheckCollision(zomb, player))
                {
                    if (player.HasChainsaw)
                    {
                        toRemove.Add(zomb);
						WTF.Instance.addDead(zomb.Position);
						Sounds.play_randomscream();
                    }
                    else
                    {
                        player.Life -= 20.0f * delta;
                        Sounds.play_randomhit();
                    }

                    continue;
                }

                Vector2 repulsForce = Vector2.Zero;

                if (GameState.state == GameState.State.PLAYER_ESCAPE || GameState.state == GameState.State.ZOMBIES_ESCAPE)
                {

                    for (int j = 0; j < zombies.Count; j++)
                    {
                        if (i == j) continue;

                        Zombie repulsZomb = zombies[j];
                        float distSquared = Vector2.DistanceSquared(zomb.Position, repulsZomb.Position);

                        if (GameState.state == GameState.State.ZOMBIES_ESCAPE)
                            repulsForce -= (zomb.Position - repulsZomb.Position) * 0.01f;

                        if (distSquared < repulsRadiusSquared)
                            repulsForce += 10000.0f * (zomb.Position - repulsZomb.Position) / distSquared;
                    }
                }

                Vector2 playerForce = Vector2.Zero;
                float distSquaredToPlayer = Vector2.DistanceSquared(zomb.Position, player.Position);

                if (GameState.state == GameState.State.PLAYER_ESCAPE)
                {
                    playerForce = -1.0f * (zomb.Position - player.Position);
                }
                else if (GameState.state == GameState.State.ZOMBIES_ESCAPE)
                {
                    playerForce = 35000 * (zomb.Position - player.Position) / distSquaredToPlayer;
                    playerForce -= (zomb.Position - player.Position) * 0.2f;
                }
                else if (GameState.state == GameState.State.THIEF)
                {
                    const float ESCAPE_TRIGGER_RADIUS_SQUARED = 15000.0f;
                    if (distSquaredToPlayer < ESCAPE_TRIGGER_RADIUS_SQUARED)
                    {
                        GameState.ChangeState(GameState.State.PLAYER_ESCAPE);
                    }
                }

                const float maxZombieSpeed = 120.0f;
                float speed = (repulsForce + playerForce).Length();
                speed = Math.Min(maxZombieSpeed, speed);

                if (speed > 0)
                {
                    zomb.Position += speed * Vector2.Normalize(repulsForce + playerForce) * delta;

                    zomb.averageMoveDir += Vector2.Normalize(repulsForce + playerForce);
                    zomb.averageMoveDir.Normalize();

                    zomb.MoveDirection = zomb.averageMoveDir;
                    zomb.LookDirection = -zomb.MoveDirection;
                }
                else
                {
                    zomb.MoveDirection = Vector2.UnitX;
                    zomb.LookDirection = -zomb.MoveDirection;
                }
            }

            foreach (Zombie zomb in toRemove)
            {
                zombies.Remove(zomb);
            }
        }

        private Vector2 averageMoveDir = Vector2.Zero;

        public Zombie()
        {
            do
            {
                Position = new Vector2(
                    ((float)WTF.Random.NextDouble() - 0.5f) * 3000,
                    ((float)WTF.Random.NextDouble() - 0.5f) * 3000);
            }
            while (Position.Length() < 250.0f);
        }

        public void Load()
        {
            base.Load("Textures//zombie");

            Animation = new MobAnimation(this.Texture, new Vector2(40, 50));
            Animation.ChangeDirection(MobAnimationDirection.BottomLeft);

            AnimationUpdateInterval = 0.120f;
            TimeFromLastAnimationUpdate = 0.120f;
        }

        public override void Update(float dt)
        {
           // MoveDirection = Vector2.Normalize(Position - PlayerPosition) * moveSpeed * dt;
            //LookDirection = -MoveDirection;

			UpdateAnimationDirection();
            UpdateAnimationFrame(dt);
        }
    }
}
